package com.koron.common.core.business.todoApproval.templates;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.koron.common.core.business.common.mapper.SystemCommonMapper;
import com.koron.common.core.business.todoApproval.bean.MessageCommonEntry;
import com.koron.common.core.business.todoApproval.bean.MessageVO;
import com.koron.common.core.business.todoApproval.bean.ZsjConfigInfo;
import com.koron.common.core.business.todoApproval.util.StringEvent;
import com.koron.common.core.business.todoApproval.util.ZsjSendTodoUtil;
import com.koron.common.core.business.workflow.service.SysWorkflowService;
import lombok.extern.slf4j.Slf4j;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;

@Slf4j
@Component
@ConditionalOnProperty(name = "oa.ekp.platform", havingValue = "zsjWater")
@ConditionalOnBean(value = {ZsjConfigInfo.class})
public class ZsjTodoApprovalModel implements TodoApprovalModel, ApplicationListener<StringEvent> {


    private static Integer SUCCESS_CODE = 200;

    @Autowired
    private ZsjSendTodoUtil zsjSendTodoUtil;

    @Autowired
    private ZsjConfigInfo zsjConfigInfo;

    @Autowired
    private SysWorkflowService sysWorkflowService;

    public static Cache<String,List<String>> cache = CacheUtil.newLFUCache(1000);


    @Override
    public String startTodo(String bizId, String title, String link, String mobileLink, List<String> accounts, String createBy, Date date, String modelName) {
        log.info("startTodo,bizId={},title={},cacheSize={}",bizId,title,cache.size());
        // 发送待办
        sendTodo(bizId, title, link, mobileLink, accounts, createBy, date, modelName);
        return null;
    }

    @Override
    public String sendTodo(String bizId, String title, String link, String mobileLink, List<String> accounts, String createBy, Date date, String modelName) {
        log.info("sendTodo,bizId={},title={},cacheSize={}",bizId,title,cache.size());
        List<MessageCommonEntry> commonEntryList = new ArrayList<>();
        try (SessionFactory sessionFactory = new SessionFactory()){
            SystemCommonMapper mapper = sessionFactory.getMapper(SystemCommonMapper.class);
            if (!CollectionUtils.isEmpty(accounts)) {
                Map<String, String> organizationCode = mapper.queryOrganizationCode(accounts);

                cache.get(bizId,() -> new ArrayList<String>()).add(bizId);

                for (String account : accounts) {
                    MessageCommonEntry commonEntry = new MessageCommonEntry();
                    commonEntry.setSendDate(DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
                    commonEntry.setLoginName(account);
                    commonEntry.setMessageId(bizId+":"+ (cache.get(bizId).size()));
                    commonEntry.setMessageTitle(title);
                    commonEntry.setPcPortalUrl(link.contains("?") ? link + "&source=OA" : link + "?source=OA"); // &source=OA
                    commonEntry.setQywxUrl(mobileLink);
                    commonEntry.setAppCode(zsjConfigInfo.getAppCode());
                    commonEntry.setMobileAppCode(zsjConfigInfo.getMobileAppCode());
                    commonEntry.setOrganizationCode(organizationCode != null ? organizationCode.getOrDefault("org_id","SCGL") : "SCGL");
                    commonEntryList.add(commonEntry);
                }
            }
            log.info("珠三角发送待办，commonEntryList={}",commonEntryList);
            zsjSendTodoUtil.addTodo(commonEntryList);
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    @Override
    public String deleteTodo(String bizId, String modelName) {
        return null;
    }

    @Override
    public String deleteTodo(String bizId, List<String> accounts, String modelName) {
        return null;
    }


    @Override
    public String setTodoDone(String bizId, List<String> accounts, String modelName) {
        log.info("setTodoDone,bizId={},cacheSize={}",bizId,cache.size());
        List<MessageCommonEntry> commonEntryList = new ArrayList<>();
        try {
            if (CollectionUtils.isEmpty(accounts)) {
                return null;
            }
            List<MessageVO> messageVOList = getMessageVOList(accounts);

            for (String account : accounts) {
                MessageVO messageVO = messageVOList.stream()
                        .filter(m -> m.getMessageId().equals(bizId + ":"+ (cache.get(bizId).size())))
                        .findFirst()
                        .orElse(null);

                if (messageVO != null) {
                    MessageCommonEntry commonEntry = new MessageCommonEntry();
                    commonEntry.setDoneDate(DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
                    commonEntry.setLoginName(account);
                    commonEntry.setMessageId( bizId + ":"+ (cache.get(bizId).size()));
                    commonEntry.setPcPortalUrl(messageVO.getPcportalurl());
                    commonEntry.setQywxUrl(messageVO.getQywxurl());
                    commonEntry.setAppCode(zsjConfigInfo.getAppCode());
                    commonEntryList.add(commonEntry);
                }
            }
            log.info("珠三角待办转已办，commonEntryList={}", commonEntryList);
            zsjSendTodoUtil.updateTodoDone(commonEntryList);
        } catch (InterruptedException e) {
            log.error("珠三角待办转已办失败！e={}",e);
        }

        return null;
    }



    private List<MessageVO> getMessageVOList(List<String> accounts) throws InterruptedException {

        if (CollectionUtils.isEmpty(accounts)){
            return new ArrayList<>();
        }

        List<MessageVO> messageVOList = new ArrayList<>();
        CountDownLatch countDownLatch = new CountDownLatch(accounts.size());

        for (String account : accounts) {
            CompletableFuture.runAsync(() -> {
                Map<String, Object> params = new HashMap<>();
                params.put("appCode", zsjConfigInfo.getAppCode());
                params.put("loginName", account);
                params.put("messageType", "TODO");
                params.put("showCount", 1000);
                params.put("currentPage", 1);
                String response = null;
                try {
                    response = zsjSendTodoUtil.messageListPage(params);
                    if (JSONUtil.parseObj(response).get("code").equals(SUCCESS_CODE)) {
                        List<MessageVO> list = JSONUtil.parseObj(response)
                                .getJSONObject("data")
                                .getJSONArray("listData")
                                .toList(MessageVO.class);
                        messageVOList.addAll(list);
                    } else {
                        log.error("当前用户：{}不存在待办信息！", account);
                    }
                } catch (InterruptedException e) {
                    log.error("珠三角获取待办信息列表失败，e={}",e);
                } finally {
                    countDownLatch.countDown();
                }
            });
        }
        countDownLatch.await();
        return messageVOList;
    }

    @Override
    public String getTodo(List<String> accounts, String rowSize, String pageNo, Integer type, String subject, String beginTime, String endTime, String modelName) {
        return null;
    }

    @Override
    public String getAccountTodo(List<String> accounts, String modelId, String modelName) {
        return null;
    }

    @Override
    public String sendRequest(String suffixUrl, String paramStr) {
        return null;
    }

    @Override
    public String getAuthorization() {
        return null;
    }

    @Override
    public String getRequestUrl(String suffixUrl) {
        return null;
    }

    @Override
    public String setAccountsTodoDone(String bizId, List<String> accounts, String modelName) {
        return null;
    }

    @Override
    public void onApplicationEvent(StringEvent stringEvent) {
        String dataId = stringEvent.getData();
        cache.remove(dataId);
    }
}
